package com.cmict.data.infra.service.source;

import com.cmict.data.infra.dal.dataobject.rdb.RdbDO;
import com.cmict.data.infra.dal.mysql.rdb.RdbMapper;
import com.cmict.data.infra.enums.rdb.RdbEnum;
import com.cmict.data.system.api.user.AdminUserApi;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import com.cmict.data.infra.controller.admin.source.vo.*;
import com.cmict.data.infra.dal.dataobject.source.SourceDO;
import com.cmict.data.framework.common.pojo.PageResult;

import com.cmict.data.infra.convert.source.SourceConvert;
import com.cmict.data.infra.dal.mysql.source.SourceMapper;

import static com.cmict.data.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cmict.data.infra.enums.ErrorCodeConstants.*;

/**
 * 数据源 Service 实现类
 *
 * @author awesome1114
 */
@Service
@Validated
public class SourceServiceImpl implements SourceService {

    @Resource
    private SourceMapper sourceMapper;

    @Resource
    private AdminUserApi adminUserApi;

    @Resource
    private RdbMapper rdbMapper;

    @Override
    public Long createSource(SourceCreateReqVO createReqVO) {
        // 插入
        this.validateCreateSourceName(createReqVO.getName());
        SourceDO source = SourceConvert.INSTANCE.convert(createReqVO);
        sourceMapper.insert(source);
        // 返回
        return source.getId();
    }

    @Override
    public void updateSource(SourceUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateSourceExists(updateReqVO.getId());
        this.validateUpdateSourceName(updateReqVO.getName(),updateReqVO.getId());
        // 更新
        SourceDO updateObj = SourceConvert.INSTANCE.convert(updateReqVO);
        sourceMapper.updateById(updateObj);
    }

    @Override
    public void deleteSource(Long id) {
        // 校验存在
        this.validateSourceExists(id);
        // 删除
        sourceMapper.deleteById(id);
    }

    private void validateCreateSourceName(String name){
        List<SourceDO> list = sourceMapper.selectListByName(name);
        if(list.size() > 0 ){
            throw exception(SOURCE_NAME_EXISTS);
        }
    }

    private void validateUpdateSourceName(String name,Long id){
        List<SourceDO> list = sourceMapper.selectListByName(name);
        if(list.size() > 0 ){
            list.stream().forEach(source->{
                if(source.getId().longValue() != id.longValue()){
                    throw exception(SOURCE_NAME_EXISTS);
                }
            });
        }
    }

    private void validateSourceExists(Long id) {
        if (sourceMapper.selectById(id) == null) {
            throw exception(SOURCE_NOT_EXISTS);
        }
    }

    @Override
    public SourceDO getSource(Long id) {
        return sourceMapper.selectById(id);
    }

    @Override
    public List<SourceDO> getSourceList(Collection<Long> ids) {
        return sourceMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<SourceRespVO> getSourcePage(SourcePageReqVO pageReqVO) {
        PageResult<SourceDO> sourceDOPageResult = sourceMapper.selectPage(pageReqVO);
        PageResult<SourceRespVO> respVOPageResult = SourceConvert.INSTANCE.convertPage(sourceDOPageResult);
        List<SourceRespVO> list = respVOPageResult.getList();
        if(list !=null && list.size() > 0){
            for (SourceRespVO sourceRespVO : list) {
                sourceRespVO.setCreator(adminUserApi.getUser(Long.valueOf(sourceRespVO.getCreator())).getCheckedData().getNickname());
                RdbDO rdbDO = rdbMapper.selectById(sourceRespVO.getDbId());
                sourceRespVO.setDbName(sourceRespVO.getDbId().equals(0L) ? RdbEnum.localDb.getIp() : (rdbDO != null ? rdbDO.getDatabaseName() : ""));
            }
        }

        return respVOPageResult;
    }

    @Override
    public List<SourceDO> getSourceList(SourceExportReqVO exportReqVO) {
        return sourceMapper.selectList(exportReqVO);
    }

    @Override
    public List<SourceDO> getSourceList() {
        return sourceMapper.getSourceList();
    }

    @Override
    public void batchDeleteSource(Collection<Long> ids) {
        sourceMapper.deleteBatchIds(ids);
    }

    @Override
    public List<SourceDO> getListchooseByExcludeId(Long excludeId) {
        return sourceMapper.getListchooseByExcludeId(excludeId);
    }

}
